/******************************************************************************************
*******************************************************************************************
***		MTConfig																		***
***																						***
***		created by Phillipp Hughes														***
***		for libMT																		***
***																						***
***		@Brief a short tool for libMT to create a calibration- / configfile				***
***																						***
*******************************************************************************************
*******************************************************************************************/


#pragma comment(lib,"libMT.lib")

#include "libMT.h"
#include <stdio.h>
#include <GL/glut.h>

//!	Holds the Window-ID
static int win;

//!	Represents the libMT-screen
mtScreen *screen;

//!	Implementation of the abstract listener class
class CTracer : public mtListener
{
public:

	//!	Constructor
	CTracer()
	{
		curPoint = 0;

		TouchData empty;
		empty.ID = empty.size = empty.X = empty.Y = 0;
		Points[0] = Points[1] = Points[2] = Points[3] = empty;
	}

	~CTracer()
	{

	}

private:

	//!	the 5 points to touch for configuration
	TouchData Points[4];

	//!	which point is currently getting configured
	unsigned int curPoint;


	//!	GL drawing function for the calibration crosses
	void drawCross(float x, float y, float size, bool cur=0)
	{
		cur ? glColor3f(1,0,0) : glColor3f(1,1,1);
		glPushMatrix();
			glTranslatef(x-(size/2),y,0);
			glBegin(GL_LINE_LOOP);
				glVertex2f(0,0);
				glVertex2f(size,0);
			glEnd();
		glPopMatrix();

		glPushMatrix();
			glTranslatef(x,y-(size/2),0);
			glBegin(GL_LINE_LOOP);
				glVertex2f(0,0);
				glVertex2f(0,size);
			glEnd();
		glPopMatrix();
	}

public:

	//!	the tracers drawing function
	void draw()
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glPushMatrix();
		glLoadIdentity();
		drawCross(-0.85f, 0.85f, curPoint==0?0.04f:0.06f,curPoint==0?1:0);
		drawCross(0.85f, 0.85f, curPoint==1?0.04f:0.06f,curPoint==1?1:0);
		drawCross(-0.85f, -0.85f, curPoint==2?0.04f:0.06f,curPoint==2?1:0);
		drawCross(0.85f, -0.85f, curPoint==3?0.04f:0.06f,curPoint==3?1:0);
		glPopMatrix();
		glFlush();
		glutSwapBuffers();
		glutPostRedisplay();
	}

	//!	what to do if a new finger appears
	virtual void fingerDown(TouchData data)
	{
		Points[curPoint] = data;
	}

	//!	what to do if the finger is moving
	virtual void fingerUpdate(TouchData data)
	{
		Points[curPoint] = data;
	}

	//!	what to do if a finger was released
	virtual void fingerUp(int id)
	{
		if(curPoint<3) curPoint++;
		else
		{
			screen->saveConfig(Points[0], Points[1], Points[2], Points[3], "");
			glutDestroyWindow(win);
			exit(0);
		}
	}
};

//!	after defining our listener-class we can add an instance
CTracer tracer;

//!	a callback for keyboard input (just quits)
void keyboard(unsigned char key, int x, int y)
{
	if(key==27)
	{
		libMT::destroy();
		glutDestroyWindow(win);
		exit(0);
	}
}

void keyboardExtra(int key, int x, int y)
{
	if(key==GLUT_KEY_LEFT)		if(screen->sensitivity<5)screen->sensitivity++;
	else if(key==GLUT_KEY_RIGHT)	if(screen->sensitivity>1)screen->sensitivity--;
	fprintf_s(stderr,"sensitivity: %i\n", screen->sensitivity);
}

//!	main drawing function
//!	only needed to call the virtual draw-function from tracer
void draw()
{
	tracer.draw();
}

//!	the programs entrypoint
int main(int argc, char* argv[])
{
	screen = libMT::getMTScreen();

	if(screen->connect()) screen->addListener((mtListener *)&tracer);
	else
	{
		libMT::destroy();
		fprintf_s(stderr,"no wiimote connected?");
		return 1;
	}

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	glViewport(0, 0, 1024, 768);
	win = glutCreateWindow("Configapp");
	glShadeModel(GL_SMOOTH);
//	glutReshapeWindow(1024, 768);
	glutKeyboardFunc(keyboard);
	glutSpecialFunc(keyboardExtra);
	glutDisplayFunc(draw);
	glLineWidth(4);

	screen->start();

	glutFullScreen();
	glutMainLoop();

	libMT::destroy();
}
